#! /usr/bin/env Python3
#coding=utf-8
"""
证券之星网股票数据爬虫模块
作者: KydGroups
版本: 1.0.0
完成日期: 2024-03-04
修改记录:
"""

from pyquery import PyQuery as pq

from KydPyPub.Sys import TypeConvert #添加字符串转换模块

class ZqzxStock():
    """
    从证券之星网络上爬取股票各种信息的类
    """
    def __init__(self):
        """
        :DESCRIPTION:
            初始化函数
        :PARAMS:
            nothing
        :RETURNS:
            nothing
        """
        self.strBonusInfoUrlFormat = "http://stock.quote.stockstar.com/dividend/bonus_%s.shtml" #股票分红信息网址格式化字符串
        self.urlheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36' }
        self.__strStoreCode = "" #股票存储代码
        self.__strStockCode = "" #股票代码
        self.dictFunc = {'Bonus': True,#是否有爬取股票分红数据功能
                         'Fina': False,  # 是否有爬取股票财务数据功能
                         'Trade': False,  # 是否有爬取股票交易时间的数据功能
                         'Close': False}  # 是否有爬取股票收盘后的数据功能


    def SetStoreCode(self, strCode:str=''):
        """
        :DESCRIPTION:
            设置股票存储代码,注意这里都是使用存储代码
        :PARAMS:
            strCode:股票的存储代码
        :RETURNS:
            True:设置成功 False:设置失败
        """
        if not strCode: #如果没有传入参数
            return False
        if not isinstance(strCode, str): #如果传入的参数不是str类型
            return False
        try:
            if len( strCode) != 8: #如果传入的代码长度不为8
                self.__strStoreCode = ""
                self.__strStockCode = ""
                return False
            else:
                self.__strStoreCode = strCode #设置股票存储代码
                self.__strStockCode = strCode[2:] #设置股票代码
                return True
        except:
            return False


    def GetCrawlerFunction(self):
        """
        :DESCRIPTION:
            获取爬虫当前能爬取的数据功能
        :PARAMS:
            nothing
        :RETURNS:
            None:出错 dict:功能设置字典
        """
        return self.dictFunc


    def CrawBonusData(self):
        """
        :DESCRITION:
            爬取股票分红信息
        :RETURNS: 爬取到的股票分红数据列表
        """
        if not self.__strStockCode:#如果没有设置股票代码
            strError = TypeConvert.StrToColorStr("使用ZqzxStock类爬取股票分红数据时_没有设置股票代码!", 'alarm')
            print(strError)
            return None
        try:
            url = self.strBonusInfoUrlFormat % self.__strStockCode#格式化基金基本信息网址
            print("正在从证券之星网站下载股票 %s 分红记录!" % self.__strStockCode)
            doc = pq(url=url, encoding='gb2312', headers=self.urlheaders, timeout=200)  #获取网页
            listTR = list(doc('table[class="globalTable trHover"] tbody tr').items())
            if not listTR:#如果没有分红记录
                return None
            listReturn = list() #返回的记录字典列表
            for tr in listTR:#循环处理每一行记录
                listTD = list(tr('td').items() ) #获取一行中每个单元格的列表
                if not listTD:#如果没有单元格数据
                    continue #路过继续循环
                if listTD[6].text() != "实施分配":#如果不是已经实施的方案,不作处理
                    continue
                else:
                    dictBonus = dict() #分红记录字典
                    dictBonus['StoreCode'] = self.__strStoreCode #设置股票存储代码
                    dictBonus['StockCode'] = self.__strStockCode #设置股票代码
                    dictBonus['AnnDate'] = listTD[0].text() #公告日期
                    dictBonus['DiviValue'] = round((TypeConvert.StrTopNumToFloat(listTD[1].text(), 0.0)/10.0), 6) #每股派息,保存6位有效数字,要交税
                    dictBonus['BonusShares'] = round(TypeConvert.StrTopNumToFloat(listTD[2].text(), 0.0)/10.0, 6) #盈利每股送股数,保存6位有效数字,要交税
                    dictBonus['AddShares'] = round(TypeConvert.StrTopNumToFloat(listTD[3].text(), 0.0 )/10.0, 6) #公积金每股转增股数,保存6位有效数字,不用交税
                    dictBonus['RegDate'] = listTD[4].text() #股权登记日
                    dictBonus['DiviDate'] = listTD[5].text() #除权除息日
                    dictBonus['ListDate'] = dictBonus['DiviDate'] #使用除权除息日作为红股上市日期
                    dictBonus['Remark'] = 'Yes'
                    if (dictBonus['DiviValue']<=0.0) and (dictBonus['BonusShares']<=0.0) and (dictBonus['AddShares'] <= 0.0):
                        continue#如果三个数字都为0，则跳过该行
                    else:
                        listReturn.append(dictBonus) #将结果添加到列表中
            print("从证券之星网站下载股票 %s 分红记录成功!" % self.__strStockCode)
            return listReturn
        except: #如果出现错误，则返回
            strError = TypeConvert.StrToColorStr("从证券之星网站下载股票 %s 分红记录失败!" % self.__strStockCode, 'alarm')
            print(strError)
            return None
